﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ListFiles;
using System.Numeric;
using System.IO;
using System.IO.Compression;
using System.Diagnostics;

namespace ListFiles
{
    class CompressedSerializer
    {
        public static void Write(Dictionary<ulong, MasterFileTableEntry> files, string filename)
        {
            // To guarantee atomicity when creating this files we first create
            // a temporary file and later move it to the desired position
            // this guarantees that the file at the final position is 
            // generated correctly
            string tempName = Path.GetTempFileName();

            using (FileStream f = new FileStream(tempName, FileMode.Create, FileAccess.Write))
            {
                using (GZipStream s = new GZipStream(f, CompressionMode.Compress))
                {
                    using (BinaryWriter w = new BinaryWriter(s))
                    {
                        w.Write((int)2);
                        w.Write(files.Count);

                        foreach (KeyValuePair<ulong, MasterFileTableEntry> file in files)
                        {
                            w.Write(file.Key);
                            w.Write(file.Value.Parent);
                            w.Write(file.Value.IsDirectory);
                            w.Write(file.Value.Filename);
                        }
                    }
                }
            }

            if (CacheExists(filename))
                File.Delete(filename);
            File.Move(tempName, filename);
        }

        public static bool CacheExists(string filename)
        {
            return File.Exists(filename);
        }

        public static void Read(Dictionary<ulong, MasterFileTableEntry> files, string filename)
        {
            files.Clear();

            using (FileStream f = new FileStream(filename, FileMode.Open))
            {
                using (GZipStream s = new GZipStream(f, CompressionMode.Decompress))
                {
                    using (BinaryReader r = new BinaryReader(s))
                    {
                        int version = r.ReadInt32();
                        Debug.Assert(version == 2);

                        int count = r.ReadInt32();

                        for (int i = 0; i < count; i++)
                        {
                            ulong key = r.ReadUInt64();
                            ulong parentfrn = r.ReadUInt64();
                            bool isdir = r.ReadBoolean();
                            string name = r.ReadString();
                            files[key] = new MasterFileTableEntry(name, parentfrn, isdir);
                        }
                    }
                }
            }
        }
    }
}
